﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Web.Script.Serialization;
using System.Reflection;
using System.Xml;

namespace Process
{
    public class ProcessEngine
    {

        private static bool isExited = false;
        private static ProcessEngine _instance;
        private ProcessEngine()
        {
            XmlDocument xml = new XmlDocument();
            xml.Load("config/Process.xml");
            startUrl = xml["Config"]["StartUrl"].InnerText;
            startPage = xml["Config"]["StartPage"].InnerText;
            adapter = xml["Config"]["Adapter"].InnerText;
            process = xml["Config"]["Process"].InnerText;
            if (startUrl == "local")
            {
                startUrl = Application.StartupPath;
            }
        }
        private static readonly object locker = new object();
        public static ProcessEngine Instance
        {
            get
            {
                lock (locker)
                {
                    if (_instance == null)
                    {
                        _instance = new ProcessEngine();
                    }
                }
                return _instance;
            }
        }
        private string startUrl;
        private string startPage;
        private string adapter;
        private string process;

        private bool isPageReload;
        public bool IsPageReload { get { return isPageReload; } }

        private string lockedPage;
        public string LockedPage { get { return lockedPage; } }

        public void SetProcess()
        {
            SetController(startPage.Split('.')[0]);

            Program.fmFrame.wbView.Navigate(startUrl + "/" + process + "/" + startPage);
        }

        public void SetController(string controllerName)
        {
            string className = "Adapter." + adapter + "." + controllerName + "Controller";
            //Type t = Assembly.Load("Process").GetType(className);
            string fileName = Application.StartupPath + "\\" + "Adapter." + adapter + ".dll";
            Type t = Assembly.LoadFile(fileName).GetType(className);
            if (t == null)
            {
                throw new Exception("未找到控制器" + className);
            }
            IanWebkitBrowser.IanBrowser.ObjectForScripting = t.GetMethod("get_Instance").Invoke(null, null);
        }

        private delegate void CrossRenderPageHandler(object inObjs, string id);
        private delegate void CrossRenderPageWithShowFlagHandler(object inObjs, string id, bool isShow);
        public void RenderPage(object inObjs, string id)
        {
            if (Program.fmFrame.wbView.InvokeRequired)
            {
                CrossRenderPageHandler handler = new CrossRenderPageHandler(RenderPage);
                Program.fmFrame.Invoke(handler, inObjs, id);
            }
            else
            {
                //Program.fmFrame.wbView.Document.InvokeScript("renderPage", new object[] { DataSerialize(inObjs), id });
                Program.fmFrame.wbView.RunScript(string.Format("renderPage('{0}','{1}');", DataSerialize(inObjs), id));
            }
        }
        public void RenderPage(object inObjs, string id, bool isShow)
        {
            if (Program.fmFrame.wbView.InvokeRequired)
            {
                CrossRenderPageWithShowFlagHandler handler = new CrossRenderPageWithShowFlagHandler(RenderPage);
                Program.fmFrame.Invoke(handler, inObjs, id, isShow);
            }
            else
            {
                //Program.fmFrame.wbView.Document.InvokeScript("renderPage", new object[] { DataSerialize(inObjs), id, isShow });
                Program.fmFrame.wbView.RunScript(string.Format("renderPage('{0}','{1}',{2});", DataSerialize(inObjs), id, isShow));
            }
        }

        public void CreateTimeout(int time, string id)
        {
            RunScript("createTimeout(" + time + ",'" + id + "');");
        }

        public void ReLoadPage()
        {
            Program.fmFrame.wbView.Refresh();
            isPageReload = true;
        }

        public void LockPage(string url)
        {
            lockedPage = url;
        }

        public void GoPage(string url)
        {
            Program.fmFrame.wbView.Navigate(startUrl + "/" + process + "/" + url.Replace('.', '/') + ".htm");
            isPageReload = false;
        }

        private delegate void CrossRunScriptHandler(string script);
        public void RunScript(string script)
        {
            if (Program.fmFrame.wbView.InvokeRequired)
            {
                CrossRunScriptHandler handler = new CrossRunScriptHandler(RunScript);
                Program.fmFrame.Invoke(handler, script);
            }
            else
            {
                //Program.fmFrame.wbView.Document.InvokeScript("eval", new object[] { script });
                Program.fmFrame.wbView.RunScript(script);
            }
        }

        public string DataSerialize(object obj)
        {
            JavaScriptSerializer jser = new JavaScriptSerializer();
            Console.WriteLine(jser.Serialize(obj));
            return jser.Serialize(obj);
        }

        public T DataDeserialize<T>(string data)
        {
            JavaScriptSerializer jser = new JavaScriptSerializer();
            return jser.Deserialize<T>(data);
        }

        public void Exit()
        {
            if (!isExited)
            {
                Application.Exit();
                isExited = true;
            }
        }
    }
}
